package appSocket

import (
	"sync"
	"time"

	"gitee.com/DengAnbang/goutils/loge"
)

const (
	MaxLifeTime      = 60
	FaultTolerantNum = 10 //容错的次数(比如MaxLifeTime为10s,FaultTolerantNum为2,则表示超过5s的时候,就发一次心跳,超过10s时,就认为超时了)
)

type SocketManage struct {
	heartbeat   bool               //心跳
	Lock        sync.RWMutex       //互斥(保证线程安全)
	SocketName  string             //客户端Socket名称
	MaxLifeTime int64              //垃圾回收时间
	Packets     map[string]*packet //保存packet的指针[SocketID] = packet
}

var socketManage = SocketManage{
	Lock:        sync.RWMutex{},
	MaxLifeTime: MaxLifeTime, //s
	Packets:     make(map[string]*packet),
}

func init() {
	if socketManage.MaxLifeTime > 0 {
		go socketManage.GC()
	}
}

//GC回收
func (sm *SocketManage) GC() {
	sm.Lock.Lock()
	defer sm.Lock.Unlock()
	for socketID, packet := range sm.Packets {
		//删除超过时限的socket
		if packet.LastTimeAccessed.Unix()+sm.MaxLifeTime < time.Now().Unix() {
			loge.E("回收:" + packet.conn.RemoteAddr().String())
			delete(sm.Packets, socketID)
		} else
		//如果超过了1/FaultTolerantNum的时间,就发一次心跳
		if packet.LastTimeAccessed.Unix()+sm.MaxLifeTime/FaultTolerantNum < time.Now().Unix() {
			go packet.Ping()
		}
	}
	//定时回收
	time.AfterFunc(time.Duration(sm.MaxLifeTime/FaultTolerantNum)*time.Second, func() { sm.GC() })
}

//添加一个
func (sm *SocketManage) Add(key string, packet *packet) {
	sm.Lock.Lock()
	defer sm.Lock.Unlock()
	packet.packetID = key
	sm.Packets[key] = packet
}

//获取一个
func (sm *SocketManage) Get(key string) *packet {
	sm.Lock.Lock()
	defer sm.Lock.Unlock()
	return sm.Packets[key]
}

//关闭一个链接
func (sm SocketManage) Close(packet *packet) {
	sm.Lock.Lock()
	defer sm.Lock.Unlock()
	packet.Close()
	for k, v := range sm.Packets {
		if packet == v {
			delete(sm.Packets, k)
		}
	}
}
